"""
Flask日志系统示例 - 展示结构化日志、日志级别、日志轮转等功能
包含请求日志、错误日志、性能监控、审计日志等
"""

from flask import Flask, request, jsonify, g
import os
import sys
import time
import traceback
from datetime import datetime, timedelta
from typing import Dict, Any, Optional
from functools import wraps
import json

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from python_backend_toolkit.logging import (
    get_logger, LogLevel, setup_logging,
    StructuredLogger, FileHandler, ConsoleHandler
)
from python_backend_toolkit.utils import generate_uuid
from python_backend_toolkit.api.responses import SuccessResponse, ErrorResponse


# ========================================================================
# 日志配置和初始化
# ========================================================================

def setup_app_logging():
    """设置应用日志配置"""
    # 设置全局日志配置
    setup_logging(
        level=LogLevel.INFO,
        format_type="json",
        include_timestamp=True,
        include_level=True,
        include_logger_name=True
    )
    
    # 创建不同用途的日志器
    loggers = {
        'app': get_logger("FlaskApp"),
        'request': get_logger("RequestLogger"),
        'error': get_logger("ErrorLogger"),
        'performance': get_logger("PerformanceLogger"),
        'audit': get_logger("AuditLogger"),
        'security': get_logger("SecurityLogger"),
        'business': get_logger("BusinessLogger")
    }
    
    return loggers


# ========================================================================
# 日志装饰器
# ========================================================================

def log_function_call(logger_name: str = "app"):
    """函数调用日志装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            logger = get_logger(logger_name)
            func_name = func.__name__
            
            # 记录函数开始
            start_time = time.time()
            logger.info(
                f"Function {func_name} started",
                function=func_name,
                args_count=len(args),
                kwargs_count=len(kwargs)
            )
            
            try:
                result = func(*args, **kwargs)
                
                # 记录函数成功完成
                duration = time.time() - start_time
                logger.info(
                    f"Function {func_name} completed successfully",
                    function=func_name,
                    duration=duration,
                    success=True
                )
                
                return result
                
            except Exception as e:
                # 记录函数异常
                duration = time.time() - start_time
                logger.error(
                    f"Function {func_name} failed",
                    function=func_name,
                    duration=duration,
                    error=str(e),
                    error_type=type(e).__name__,
                    success=False
                )
                raise
                
        return wrapper
    return decorator


def log_performance(threshold_seconds: float = 1.0):
    """性能监控装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            logger = get_logger("PerformanceLogger")
            func_name = func.__name__
            
            start_time = time.time()
            result = func(*args, **kwargs)
            duration = time.time() - start_time
            
            # 如果执行时间超过阈值，记录性能警告
            if duration > threshold_seconds:
                logger.warning(
                    f"Slow function execution detected",
                    function=func_name,
                    duration=duration,
                    threshold=threshold_seconds,
                    performance_issue=True
                )
            else:
                logger.debug(
                    f"Function performance",
                    function=func_name,
                    duration=duration
                )
            
            return result
        return wrapper
    return decorator


def audit_log(action: str, resource: str = None):
    """审计日志装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            logger = get_logger("AuditLogger")
            
            # 获取用户信息（如果有的话）
            user_id = getattr(g, 'user_id', 'anonymous')
            request_id = getattr(g, 'request_id', 'unknown')
            
            # 记录操作开始
            logger.info(
                f"Audit: {action} started",
                action=action,
                resource=resource,
                user_id=user_id,
                request_id=request_id,
                ip_address=request.remote_addr if request else None,
                user_agent=request.headers.get('User-Agent') if request else None
            )
            
            try:
                result = func(*args, **kwargs)
                
                # 记录操作成功
                logger.info(
                    f"Audit: {action} completed",
                    action=action,
                    resource=resource,
                    user_id=user_id,
                    request_id=request_id,
                    success=True
                )
                
                return result
                
            except Exception as e:
                # 记录操作失败
                logger.error(
                    f"Audit: {action} failed",
                    action=action,
                    resource=resource,
                    user_id=user_id,
                    request_id=request_id,
                    error=str(e),
                    success=False
                )
                raise
                
        return wrapper
    return decorator


# ========================================================================
# 业务逻辑示例
# ========================================================================

class UserService:
    """用户服务示例"""
    
    def __init__(self):
        self.logger = get_logger("BusinessLogger")
        self.users = {}  # 模拟用户数据
    
    @log_function_call("business")
    @audit_log("create_user", "user")
    def create_user(self, username: str, email: str) -> Dict[str, Any]:
        """创建用户"""
        user_id = generate_uuid()
        
        # 业务日志
        self.logger.info(
            "Creating new user",
            username=username,
            email=email,
            user_id=user_id
        )
        
        # 模拟业务逻辑
        if username in self.users:
            self.logger.warning(
                "User creation failed - username already exists",
                username=username,
                conflict=True
            )
            raise ValueError(f"Username '{username}' already exists")
        
        user = {
            "id": user_id,
            "username": username,
            "email": email,
            "created_at": datetime.utcnow().isoformat(),
            "status": "active"
        }
        
        self.users[username] = user
        
        self.logger.info(
            "User created successfully",
            user_id=user_id,
            username=username
        )
        
        return user
    
    @log_function_call("business")
    @log_performance(0.5)
    def get_user(self, username: str) -> Optional[Dict[str, Any]]:
        """获取用户"""
        self.logger.debug(
            "Retrieving user",
            username=username
        )
        
        # 模拟数据库查询延迟
        time.sleep(0.1)
        
        user = self.users.get(username)
        
        if user:
            self.logger.info(
                "User retrieved successfully",
                username=username,
                user_id=user['id']
            )
        else:
            self.logger.warning(
                "User not found",
                username=username
            )
        
        return user
    
    @audit_log("delete_user", "user")
    def delete_user(self, username: str) -> bool:
        """删除用户"""
        self.logger.info(
            "Deleting user",
            username=username
        )
        
        if username in self.users:
            del self.users[username]
            self.logger.info(
                "User deleted successfully",
                username=username
            )
            return True
        else:
            self.logger.warning(
                "User deletion failed - user not found",
                username=username
            )
            return False
    
    def list_users(self) -> list:
        """获取用户列表"""
        self.logger.info(
            "Listing users",
            total_users=len(self.users)
        )
        return list(self.users.values())


class OrderService:
    """订单服务示例"""
    
    def __init__(self):
        self.logger = get_logger("BusinessLogger")
        self.orders = {}
    
    @log_function_call("business")
    @audit_log("create_order", "order")
    @log_performance(2.0)
    def create_order(self, user_id: str, items: list, total_amount: float) -> Dict[str, Any]:
        """创建订单"""
        order_id = generate_uuid()
        
        self.logger.info(
            "Creating new order",
            order_id=order_id,
            user_id=user_id,
            items_count=len(items),
            total_amount=total_amount
        )
        
        # 模拟复杂的业务逻辑
        time.sleep(0.5)
        
        # 验证订单
        if total_amount <= 0:
            self.logger.error(
                "Order creation failed - invalid amount",
                order_id=order_id,
                total_amount=total_amount,
                validation_error=True
            )
            raise ValueError("Total amount must be positive")
        
        if not items:
            self.logger.error(
                "Order creation failed - no items",
                order_id=order_id,
                validation_error=True
            )
            raise ValueError("Order must contain at least one item")
        
        order = {
            "id": order_id,
            "user_id": user_id,
            "items": items,
            "total_amount": total_amount,
            "status": "pending",
            "created_at": datetime.utcnow().isoformat()
        }
        
        self.orders[order_id] = order
        
        self.logger.info(
            "Order created successfully",
            order_id=order_id,
            user_id=user_id,
            status="pending"
        )
        
        return order
    
    @audit_log("process_payment", "order")
    def process_payment(self, order_id: str) -> bool:
        """处理支付"""
        self.logger.info(
            "Processing payment",
            order_id=order_id
        )
        
        order = self.orders.get(order_id)
        if not order:
            self.logger.error(
                "Payment processing failed - order not found",
                order_id=order_id
            )
            return False
        
        # 模拟支付处理
        time.sleep(1.0)
        
        # 模拟支付失败的情况
        import random
        if random.random() < 0.2:  # 20% 失败率
            self.logger.error(
                "Payment processing failed",
                order_id=order_id,
                user_id=order['user_id'],
                amount=order['total_amount'],
                payment_error=True
            )
            order['status'] = 'payment_failed'
            return False
        
        order['status'] = 'paid'
        order['paid_at'] = datetime.utcnow().isoformat()
        
        self.logger.info(
            "Payment processed successfully",
            order_id=order_id,
            user_id=order['user_id'],
            amount=order['total_amount']
        )
        
        return True


def create_logging_app() -> Flask:
    """创建日志示例Flask应用"""
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'logging-demo-secret'
    
    # 初始化日志
    loggers = setup_app_logging()
    
    # 初始化服务
    user_service = UserService()
    order_service = OrderService()
    
    # ========================================================================
    # 中间件
    # ========================================================================
    
    @app.before_request
    def before_request():
        """请求前处理"""
        g.request_id = generate_uuid()
        g.start_time = time.time()
        g.user_id = request.headers.get('X-User-ID', 'anonymous')
        
        # 请求日志
        loggers['request'].info(
            "Request started",
            request_id=g.request_id,
            method=request.method,
            path=request.path,
            query_string=request.query_string.decode(),
            user_agent=request.headers.get('User-Agent'),
            ip_address=request.remote_addr,
            user_id=g.user_id
        )
    
    @app.after_request
    def after_request(response):
        """请求后处理"""
        duration = time.time() - g.start_time
        
        # 请求完成日志
        loggers['request'].info(
            "Request completed",
            request_id=g.request_id,
            method=request.method,
            path=request.path,
            status_code=response.status_code,
            duration=duration,
            user_id=g.user_id
        )
        
        # 性能监控
        if duration > 2.0:
            loggers['performance'].warning(
                "Slow request detected",
                request_id=g.request_id,
                path=request.path,
                duration=duration,
                performance_issue=True
            )
        
        return response
    
    @app.errorhandler(Exception)
    def handle_exception(e):
        """全局异常处理"""
        error_id = generate_uuid()
        
        # 错误日志
        loggers['error'].error(
            "Unhandled exception occurred",
            error_id=error_id,
            request_id=getattr(g, 'request_id', 'unknown'),
            error_type=type(e).__name__,
            error_message=str(e),
            traceback=traceback.format_exc(),
            path=request.path,
            method=request.method,
            user_id=getattr(g, 'user_id', 'unknown')
        )
        
        # 安全日志（如果是安全相关错误）
        if isinstance(e, (PermissionError, ValueError)):
            loggers['security'].warning(
                "Security-related error",
                error_id=error_id,
                error_type=type(e).__name__,
                ip_address=request.remote_addr,
                user_id=getattr(g, 'user_id', 'unknown')
            )
        
        return jsonify(ErrorResponse.create(
            message="Internal server error",
            error_id=error_id
        ).dict()), 500
    
    # ========================================================================
    # 用户管理API
    # ========================================================================
    
    @app.route('/users', methods=['POST'])
    def create_user():
        """创建用户"""
        try:
            data = request.get_json()
            username = data.get('username', '').strip()
            email = data.get('email', '').strip()
            
            if not username or not email:
                loggers['app'].warning(
                    "User creation failed - missing required fields",
                    username=username,
                    email=email,
                    validation_error=True
                )
                return jsonify(ErrorResponse.create(
                    message="Username and email are required"
                ).dict()), 400
            
            user = user_service.create_user(username, email)
            
            response = SuccessResponse.create(
                data={"user": user},
                message="User created successfully"
            )
            return jsonify(response.dict()), 201
            
        except ValueError as e:
            return jsonify(ErrorResponse.create(
                message=str(e)
            ).dict()), 409
        except Exception as e:
            loggers['error'].error(
                "Unexpected error in create_user",
                error=str(e),
                error_type=type(e).__name__
            )
            raise
    
    @app.route('/users/<username>', methods=['GET'])
    def get_user(username: str):
        """获取用户"""
        try:
            user = user_service.get_user(username)
            
            if not user:
                return jsonify(ErrorResponse.create(
                    message="User not found"
                ).dict()), 404
            
            response = SuccessResponse.create(
                data={"user": user},
                message="User retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            loggers['error'].error(
                "Error in get_user",
                username=username,
                error=str(e)
            )
            raise
    
    @app.route('/users', methods=['GET'])
    def list_users():
        """获取用户列表"""
        try:
            users = user_service.list_users()
            
            response = SuccessResponse.create(
                data={"users": users, "total": len(users)},
                message="Users retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            loggers['error'].error(
                "Error in list_users",
                error=str(e)
            )
            raise
    
    @app.route('/users/<username>', methods=['DELETE'])
    def delete_user(username: str):
        """删除用户"""
        try:
            success = user_service.delete_user(username)
            
            if not success:
                return jsonify(ErrorResponse.create(
                    message="User not found"
                ).dict()), 404
            
            response = SuccessResponse.create(
                message="User deleted successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            loggers['error'].error(
                "Error in delete_user",
                username=username,
                error=str(e)
            )
            raise
    
    # ========================================================================
    # 订单管理API
    # ========================================================================
    
    @app.route('/orders', methods=['POST'])
    def create_order():
        """创建订单"""
        try:
            data = request.get_json()
            user_id = data.get('user_id', '').strip()
            items = data.get('items', [])
            total_amount = data.get('total_amount', 0)
            
            if not user_id:
                return jsonify(ErrorResponse.create(
                    message="User ID is required"
                ).dict()), 400
            
            order = order_service.create_order(user_id, items, total_amount)
            
            response = SuccessResponse.create(
                data={"order": order},
                message="Order created successfully"
            )
            return jsonify(response.dict()), 201
            
        except ValueError as e:
            return jsonify(ErrorResponse.create(
                message=str(e)
            ).dict()), 400
        except Exception as e:
            loggers['error'].error(
                "Error in create_order",
                error=str(e)
            )
            raise
    
    @app.route('/orders/<order_id>/payment', methods=['POST'])
    def process_payment(order_id: str):
        """处理支付"""
        try:
            success = order_service.process_payment(order_id)
            
            if not success:
                return jsonify(ErrorResponse.create(
                    message="Payment processing failed"
                ).dict()), 400
            
            response = SuccessResponse.create(
                message="Payment processed successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            loggers['error'].error(
                "Error in process_payment",
                order_id=order_id,
                error=str(e)
            )
            raise
    
    # ========================================================================
    # 日志管理API
    # ========================================================================
    
    @app.route('/logs/test', methods=['POST'])
    def test_logging():
        """测试各种日志级别"""
        try:
            data = request.get_json() or {}
            test_type = data.get('type', 'all')
            
            logger = loggers['app']
            
            if test_type in ['all', 'levels']:
                # 测试不同日志级别
                logger.debug("This is a debug message", test_type="debug")
                logger.info("This is an info message", test_type="info")
                logger.warning("This is a warning message", test_type="warning")
                logger.error("This is an error message", test_type="error")
            
            if test_type in ['all', 'structured']:
                # 测试结构化日志
                logger.info(
                    "Structured log example",
                    user_id="12345",
                    action="test_logging",
                    metadata={
                        "browser": "Chrome",
                        "version": "91.0",
                        "platform": "Windows"
                    },
                    metrics={
                        "response_time": 0.123,
                        "memory_usage": 45.6
                    }
                )
            
            if test_type in ['all', 'performance']:
                # 测试性能日志
                start_time = time.time()
                time.sleep(0.1)  # 模拟处理时间
                duration = time.time() - start_time
                
                loggers['performance'].info(
                    "Performance test completed",
                    operation="test_operation",
                    duration=duration,
                    status="success"
                )
            
            if test_type in ['all', 'audit']:
                # 测试审计日志
                loggers['audit'].info(
                    "Audit log test",
                    action="test_audit",
                    resource="test_resource",
                    user_id=g.user_id,
                    ip_address=request.remote_addr,
                    timestamp=datetime.utcnow().isoformat()
                )
            
            if test_type in ['all', 'security']:
                # 测试安全日志
                loggers['security'].warning(
                    "Security event simulation",
                    event_type="suspicious_activity",
                    ip_address=request.remote_addr,
                    user_id=g.user_id,
                    details="Multiple failed login attempts"
                )
            
            response = SuccessResponse.create(
                data={"test_type": test_type},
                message="Logging test completed successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            loggers['error'].error(
                "Error in test_logging",
                error=str(e)
            )
            raise
    
    @app.route('/logs/error-test', methods=['POST'])
    def test_error_logging():
        """测试错误日志"""
        data = request.get_json() or {}
        error_type = data.get('error_type', 'generic')
        
        if error_type == 'value_error':
            raise ValueError("This is a test ValueError")
        elif error_type == 'permission_error':
            raise PermissionError("This is a test PermissionError")
        elif error_type == 'zero_division':
            return jsonify({"result": 1 / 0})
        else:
            raise Exception("This is a test generic exception")
    
    @app.route('/logs/stats', methods=['GET'])
    def get_log_stats():
        """获取日志统计信息"""
        try:
            # 这里可以实现日志统计逻辑
            # 在实际应用中，可能需要从日志文件或日志存储系统中获取统计信息
            
            stats = {
                "total_requests": 100,  # 示例数据
                "error_count": 5,
                "warning_count": 12,
                "average_response_time": 0.234,
                "slow_requests": 3,
                "security_events": 1,
                "audit_events": 25
            }
            
            response = SuccessResponse.create(
                data=stats,
                message="Log statistics retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            loggers['error'].error(
                "Error in get_log_stats",
                error=str(e)
            )
            raise
    
    # ========================================================================
    # 应用信息
    # ========================================================================
    
    @app.route('/health', methods=['GET'])
    def health_check():
        """健康检查"""
        loggers['app'].info("Health check requested")
        
        return jsonify({
            "status": "healthy",
            "timestamp": datetime.utcnow().isoformat(),
            "logging": "active"
        })
    
    @app.route('/info', methods=['GET'])
    def app_info():
        """应用信息"""
        return jsonify({
            "name": "Flask Logging Example",
            "version": "1.0.0",
            "description": "Flask日志系统示例应用",
            "logging_features": [
                "结构化日志",
                "多级别日志",
                "请求日志",
                "错误日志",
                "性能监控",
                "审计日志",
                "安全日志"
            ],
            "endpoints": {
                "users": [
                    "POST /users",
                    "GET  /users",
                    "GET  /users/<username>",
                    "DELETE /users/<username>"
                ],
                "orders": [
                    "POST /orders",
                    "POST /orders/<id>/payment"
                ],
                "logging": [
                    "POST /logs/test",
                    "POST /logs/error-test",
                    "GET  /logs/stats"
                ]
            },
            "log_levels": ["DEBUG", "INFO", "WARNING", "ERROR"],
            "loggers": [
                "FlaskApp",
                "RequestLogger",
                "ErrorLogger",
                "PerformanceLogger",
                "AuditLogger",
                "SecurityLogger",
                "BusinessLogger"
            ]
        })
    
    return app


if __name__ == '__main__':
    app = create_logging_app()
    
    print("=" * 60)
    print("Flask Logging Example")
    print("=" * 60)
    print("日志系统功能演示:")
    print("  用户管理:")
    print("    POST   /users - 创建用户")
    print("    GET    /users - 获取用户列表")
    print("    GET    /users/<username> - 获取用户详情")
    print("    DELETE /users/<username> - 删除用户")
    print()
    print("  订单管理:")
    print("    POST /orders - 创建订单")
    print("    POST /orders/<id>/payment - 处理支付")
    print()
    print("  日志测试:")
    print("    POST /logs/test - 测试各种日志功能")
    print("    POST /logs/error-test - 测试错误日志")
    print("    GET  /logs/stats - 获取日志统计")
    print()
    print("  特性:")
    print("    - 结构化日志记录")
    print("    - 多级别日志支持")
    print("    - 请求/响应日志")
    print("    - 性能监控日志")
    print("    - 审计日志")
    print("    - 安全事件日志")
    print("    - 函数调用装饰器")
    print("    - 全局异常处理")
    print("=" * 60)
    
    app.run(
        host='0.0.0.0',
        port=5005,
        debug=True
    )